package com.zxy.ziems.server.energy.service.impl;

import com.zxy.ziems.server.classify.pojo.bo.ClassifyMultiple;
import com.zxy.ziems.server.classify.pojo.entity.Classify;
import com.zxy.ziems.server.classify.pojo.entity.ClassifyDeviceProperty;
import com.zxy.ziems.server.classify.service.ClassifyDevicePropertyService;
import com.zxy.ziems.server.classify.service.ClassifyService;
import com.zxy.ziems.server.dto.DeviceMeasureDateGroupDto;
import com.zxy.ziems.server.energy.pojo.dto.DeviceMeasureDateDTO;
import com.zxy.ziems.server.energy.service.DeviceMeasureDataService;
import com.zxy.ziems.server.energy.service.DeviceTypeDataService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName: DeviceTypeDataServicelImpl
 * @Author: yanzhiwei
 * @Description:
 * @Date: 2024/4/2 10:28
 */
@Service
public class DeviceTypeDataServiceImpl implements DeviceTypeDataService {
    @Autowired
    private DeviceMeasureDataService deviceMeasureDataService;
    @Autowired
    private ClassifyService classifyService;
    @Autowired
    private ClassifyDevicePropertyService classifyDevicePropertyService;


    @Override
    public List<DeviceMeasureDateDTO> sumTree(String classifyId, String dateType, LocalDate start, LocalDate end, Set<String> deviceIds, String dataTypeId) {
        // 获取分类信息
        List<Classify> classifyList = classifyService.classifyListByClassifyId(classifyId);
        List<ClassifyMultiple> classifyMultipleList = classifyList.stream().map(m -> {
            ClassifyMultiple classifyMultiple = new ClassifyMultiple();
            BeanUtils.copyProperties(m, classifyMultiple);
            return classifyMultiple;
        }).collect(Collectors.toList());

        List<String> classifyIds = classifyList.stream().map(Classify::getClassifyId).collect(Collectors.toList());


        ClassifyMultiple root = classifyMultipleList.stream().filter(m -> m.getClassifyId().equals(classifyId)).findAny().orElse(new ClassifyMultiple());
        root.setNewMultiple(root.getMultiple());

        // 分类树统计
        traverseTree(root, classifyMultipleList);

        // 获取所有设备结果
        List<DeviceMeasureDateGroupDto> deviceMeasureDateDtoList = deviceMeasureDataService.getDeviceSum(dateType, start, end, deviceIds, dataTypeId, classifyIds);

        // 根据时间分组
        Map<String, List<DeviceMeasureDateGroupDto>> map = deviceMeasureDateDtoList.stream().collect(Collectors.groupingBy(m -> m.getDayStr()));

        // 各分组求和
        List<DeviceMeasureDateDTO> deviceMeasureDateDTOList1 = extracted(map);

        return deviceMeasureDateDTOList1;
    }
    @Override
    public List<DeviceMeasureDateDTO> sumTreeReal(String classifyId, String dateType, LocalDate start, LocalDate end, Set<String> deviceIds, String dataTypeId) {
        // 获取分类信息
        List<Classify> classifyList = classifyService.classifyListByClassifyId(classifyId);
        List<ClassifyMultiple> classifyMultipleList = classifyList.stream().map(m -> {
            ClassifyMultiple classifyMultiple = new ClassifyMultiple();
            BeanUtils.copyProperties(m, classifyMultiple);
            return classifyMultiple;
        }).collect(Collectors.toList());

        List<String> classifyIds = classifyList.stream().map(Classify::getClassifyId).collect(Collectors.toList());


        ClassifyMultiple root = classifyMultipleList.stream().filter(m -> m.getClassifyId().equals(classifyId)).findAny().orElse(new ClassifyMultiple());
        root.setNewMultiple(root.getMultiple());

        // 分类树统计
        traverseTree(root, classifyMultipleList);

        // 获取所有设备结果
        List<DeviceMeasureDateGroupDto> deviceMeasureDateDtoList = deviceMeasureDataService.getDeviceRealSum(dateType, start, end, deviceIds, dataTypeId, classifyIds);

        // 根据时间分组
        Map<String, List<DeviceMeasureDateGroupDto>> map = deviceMeasureDateDtoList.stream().collect(Collectors.groupingBy(m -> m.getDayStr()));

        // 各分组求和
        List<DeviceMeasureDateDTO> deviceMeasureDateDTOList1 = extracted(map);

        return deviceMeasureDateDTOList1;
    }

    @Override
    public List<DeviceMeasureDateDTO> avgTree(String classifyId, String dateType, LocalDate start, LocalDate end, Set<String> deviceIds, String dataTypeId) {
        // 获取分类信息
        List<Classify> classifyList = classifyService.classifyListByClassifyId(classifyId);

        List<String> classifyIds = classifyList.stream().map(Classify::getClassifyId).collect(Collectors.toList());

        // 获取所有设备结果
        List<DeviceMeasureDateGroupDto> deviceMeasureDateDtoList = deviceMeasureDataService.getDeviceAvg(dateType, start, end, deviceIds, dataTypeId, classifyIds);

        // 根据时间分组
        Map<String, List<DeviceMeasureDateGroupDto>> map = deviceMeasureDateDtoList.stream().collect(Collectors.groupingBy(m -> m.getDayStr()));

        // 各分组求和
        List<DeviceMeasureDateDTO> deviceMeasureDateDTOList1 = extractedSvg(map);

        return deviceMeasureDateDTOList1;
    }

    /**
     * 各分组求和
     *
     * @param map
     * @return
     */
    private List<DeviceMeasureDateDTO> extracted(Map<String, List<DeviceMeasureDateGroupDto>> map) {
        List<DeviceMeasureDateDTO> dateDtos = new ArrayList<>();
        for (String s : map.keySet()) {
            List<DeviceMeasureDateGroupDto> deviceMeasureDateGroupDtoList = map.get(s);
            BigDecimal bigDecimal = new BigDecimal(0);
            BigDecimal costDecimal = new BigDecimal(0);
            for (DeviceMeasureDateGroupDto deviceMeasureDateGroupDto : deviceMeasureDateGroupDtoList) {
                bigDecimal = bigDecimal.add(deviceMeasureDateGroupDto.getStatistic());
                if (deviceMeasureDateGroupDto.getCost() != null) {
                    costDecimal = costDecimal.add(deviceMeasureDateGroupDto.getCost());
                }
            }
            DeviceMeasureDateDTO deviceMeasureDateDto = new DeviceMeasureDateDTO();
            deviceMeasureDateDto.setDayStr(s);
            deviceMeasureDateDto.setStatistic(bigDecimal);
            deviceMeasureDateDto.setCost(costDecimal);
            dateDtos.add(deviceMeasureDateDto);
        }
        return dateDtos;
    }

    /**
     * 各分组求平均
     *
     * @param map
     * @return
     */
    private List<DeviceMeasureDateDTO> extractedSvg(Map<String, List<DeviceMeasureDateGroupDto>> map) {
        List<DeviceMeasureDateDTO> dateDtos = new ArrayList<>();
        for (String s : map.keySet()) {
            List<DeviceMeasureDateGroupDto> deviceMeasureDateGroupDtoList = map.get(s);
            BigDecimal bigDecimal = new BigDecimal(0);
            BigDecimal costDecimal = new BigDecimal(0);
            for (DeviceMeasureDateGroupDto deviceMeasureDateGroupDto : deviceMeasureDateGroupDtoList) {
                bigDecimal = bigDecimal.add(deviceMeasureDateGroupDto.getStatistic());
                if (deviceMeasureDateGroupDto.getCost() != null) {
                    costDecimal = costDecimal.add(deviceMeasureDateGroupDto.getCost());
                }
            }
            DeviceMeasureDateDTO deviceMeasureDateDto = new DeviceMeasureDateDTO();
            deviceMeasureDateDto.setDayStr(s);
            if (deviceMeasureDateGroupDtoList.size() > 0) {
                // 分组下数据求平均
                bigDecimal = bigDecimal.divide(new BigDecimal(deviceMeasureDateGroupDtoList.size()), 2, RoundingMode.HALF_UP);
            }
            deviceMeasureDateDto.setStatistic(bigDecimal);
            deviceMeasureDateDto.setCost(costDecimal);
            dateDtos.add(deviceMeasureDateDto);
        }
        return dateDtos;
    }

    /**
     * 计算系数*值
     *
     * @param root
     * @param classifyMultipleList
     * @param deviceMeasureDateDtoList
     */
    private void multipleDevice(ClassifyMultiple root, List<ClassifyMultiple> classifyMultipleList, List<DeviceMeasureDateGroupDto> deviceMeasureDateDtoList) {
        // 处理当前节点
        System.out.println(root.getClassifyName());


        // 获取当前节点所有值
        List<ClassifyMultiple> classifyList1 = classifyMultipleList.stream().filter(m -> m.getParentClassifyId() != null && m.getParentClassifyId().equals(root.getClassifyId())).collect(Collectors.toList());

        // 遍历所有子节点
        for (ClassifyMultiple child : classifyList1) {
            child.setNewMultiple(child.getMultiple().multiply(root.getNewMultiple()));

            extracted(deviceMeasureDateDtoList, child);

            multipleDevice(child, classifyMultipleList, deviceMeasureDateDtoList);

        }
    }


    private void extracted(List<DeviceMeasureDateGroupDto> deviceMeasureDateDtoList, ClassifyMultiple child) {
        List<ClassifyDeviceProperty> property = classifyDevicePropertyService.getByClassId(child.getClassifyId());

        List<String> deviceIds = property.stream().map(m -> m.getDeviceId()).collect(Collectors.toList());

        List<DeviceMeasureDateGroupDto> deviceMeasureDateGroupDtoList = deviceMeasureDateDtoList.stream().filter(m -> deviceIds.contains(m.getDeviceId())).collect(Collectors.toList());
        deviceMeasureDateGroupDtoList.stream().map(m -> {
            m.setStatistic(m.getStatistic().multiply(child.getNewMultiple()));
            return m;
        }).collect(Collectors.toList());
    }


//    /**
//     * 获取设备采集统计集
//     *
//     * @param queryType
//     * @param startDay
//     * @param endDay
//     * @param classify
//     * @param deviceIdSet
//     * @param devicePropertyId
//     * @return
//     */
//    private List<DeviceMeasureDateDto> getDeviceMeasureDateDtos(String queryType, String startDay, String endDay, Classify classify, Set<String> deviceIdSet, String devicePropertyId) {
//        List<DeviceMeasureDateGroupDto> dateDtos = new ArrayList<>();
//        if (classify.getCountType().equals(ClassifyCountType.POINT_COUNT)) {
//            // 如果是平均，获取平均的统计
//            dateDtos = deviceMeasureDataService.getAvg(queryType, DateUtils.checkFormat(startDay, YMD_PATTERN),
//                    DateUtils.checkFormat(endDay, YMD_PATTERN), deviceIdSet, devicePropertyId);
//        } else if (classify.getCountType().equals(ClassifyCountType.CLASSIFY_COUNT)) {
//            // 如果是求和，获取求和统计
//            dateDtos = deviceMeasureDataService.getDeviceSum(queryType, DateUtils.checkFormat(startDay, YMD_PATTERN),
//                    DateUtils.checkFormat(endDay, YMD_PATTERN), deviceIdSet, devicePropertyId);
//        }
//        return dateDtos;
//    }


    /**
     * @param node
     * @param classifyMultipleList
     */
    public static void traverseTree(ClassifyMultiple node, List<ClassifyMultiple> classifyMultipleList) {
        // 处理当前节点
        System.out.println(node.getClassifyName());


        // 获取当前节点所有值
        List<ClassifyMultiple> classifyList1 = classifyMultipleList.stream().filter(m -> m.getParentClassifyId() != null && m.getParentClassifyId().equals(node.getClassifyId())).collect(Collectors.toList());

        // 遍历所有子节点
        for (ClassifyMultiple child : classifyList1) {
            child.setNewMultiple(child.getMultiple().multiply(node.getNewMultiple()));
            traverseTree(child, classifyMultipleList);
        }
    }


}
